package com.lagou.edu.filter;

import com.lagou.edu.feign.UserFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Heweipo on 2021/2/15.
 */
@Component
@Slf4j
public class LoginFilter implements GlobalFilter, Ordered {

    private static Set<String> unFilterUrl;

    static {
        unFilterUrl = new HashSet<>();
        unFilterUrl.add("/user/register/");
        unFilterUrl.add("/user/isRegistered/");
        unFilterUrl.add("/user/login/");
        unFilterUrl.add("/code/validate/");
        unFilterUrl.add("/code/create/");
        unFilterUrl.add("/email/");
    }

    @Autowired
    private UserFeignClient userFeignClient;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        String path = exchange.getRequest().getURI().getPath();
        for (String s : unFilterUrl){
            if(path.startsWith(s)){
                log.info("请求的 URI：{} 无需拦截", path);
                return chain.filter(exchange);
            }
        }

        // cookie 校验
        MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
        List<HttpCookie> tokenCookies = cookies.get("tokenId");
        if(!CollectionUtils.isEmpty(tokenCookies)){
            for (HttpCookie tokenCookie : tokenCookies) {
                String value = tokenCookie.getValue();
                String validate = userFeignClient.validate(value);
                if(validate != null){
                    return chain.filter(exchange);
                }
            }
        }

        log.info("请求的 URI：{} 被拦截，且 token 校验未通过，需跳转到登录页面", path);
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码
        String data = "Request be denied! token is invalid";
        DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
        return response.writeWith(Mono.just(wrap));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
